package com.xiaoma.common.utils

import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import java.io.File
import java.io.PrintStream
import java.text.SimpleDateFormat

class XmCrashHandler private constructor() : Thread.UncaughtExceptionHandler {
    private var defHandler: Thread.UncaughtExceptionHandler? = null
    private lateinit var mContext: Context

    @SuppressLint("SimpleDateFormat")
    private val defaultFormat = SimpleDateFormat("yyyy_MM_dd_HH.mm.ss.SSS")


    override fun uncaughtException(t: Thread, e: Throwable) {
        // 异常Crash打印到本地文件
        Log.e(TAG, "uncaughtException")
        saveCrashLog(t, e)
        if (defHandler != null) {
            defHandler!!.uncaughtException(t, e)
        }
    }

    private fun saveCrashLog(t: Thread, e: Throwable): Boolean {
        Log.e(TAG, "saveCrashLog")
        try {
            val df = defaultFormat
            val parentFilePath = getParentFile(mContext).absolutePath + File.separator + "log/crash/"
            val dir = File(parentFilePath)
            if (!dir.exists()) {
                dir.mkdirs()
            }
            val pkgName = mContext.packageName
            val timeStamp = df.format(System.currentTimeMillis()).toString()
            val f = File(parentFilePath,
                "crash_" + pkgName + "_" + timeStamp + ".log")
            if (f.exists()) {
                f.delete()
            }
            f.createNewFile()
            e.printStackTrace(PrintStream(f))
        } catch (ex: Exception) {
            ex.printStackTrace()
            Log.e(TAG, "saveCrashLog() Exception: $ex")
        }
        return true
    }

    private fun getParentFile(context: Context): File {
        val internalFile = context.filesDir
        return context.getExternalFilesDir(null) ?: internalFile
    }

    @Synchronized
    fun init(context: Context) {
        mContext = context.applicationContext
        defHandler = Thread.getDefaultUncaughtExceptionHandler()
        Thread.setDefaultUncaughtExceptionHandler(this)
    }

    companion object {
        private val TAG = XmCrashHandler::class.java.simpleName + "Tag"
        val instance by lazy { XmCrashHandler() }
    }
}